package com.dhemery.mack.gui;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.TextViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.EditorPart;

import com.dhemery.mack.adapters.NodeEditorInput;

//TODO Test this class
public class NodeEditor extends EditorPart implements ModifyListener {
	public static final String ID = "com.dhemery.mack.editor.Node";
	private StyledText descriptionBoxStyledText;
	private boolean dirty;
	private NodeEditorInput input;
	private Text nameBox;
	private boolean subscribed;

	@Override
	public void createPartControl(Composite parent) {
		Composite top = new Composite(parent, SWT.NONE);
		initializeLayout(top);
		initializeEditorAreas(top);
		fillEditorAreas();
		subscribeToEditorAreaChanges();
	}

	@Override
	public void dispose() {
		unsubscribeFromEditorAreaChanges();
		super.dispose();
	}

	@Override
	public void doSave(IProgressMonitor monitor) {
		input.setName(nameBox.getText());
		input.setDescription(descriptionBoxStyledText.getText());
		setPartName(input.getName());
		markAsNotDirty();
	}

	@Override
	public void doSaveAs() {
	}

	private void fillEditorAreas() {
		nameBox.setText(input.getName());
		descriptionBoxStyledText.setText(getItemDescription());
	}

	private String getItemDescription() {
		return input.getDescription();
	}

	@Override
	public void init(IEditorSite site, IEditorInput input)
			throws PartInitException {
		this.input = (NodeEditorInput)input;
		setSite(site);
		setInput(input);
		setPartName(input.getName());
	}

	private void initializeDescriptionArea(Composite top) {
		initializeDescriptionLabel(top);
		initializeDescriptionBox(top);
	}

	private void initializeDescriptionBox(Composite top) {
		TextViewer viewer = new TextViewer(top, SWT.WRAP | SWT.BORDER | SWT.V_SCROLL);
		viewer.setDocument(new Document());
		viewer.setEditable(true);
		descriptionBoxStyledText = viewer.getTextWidget();
		descriptionBoxStyledText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
		descriptionBoxStyledText.setBackground(descriptionBoxStyledText.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
		descriptionBoxStyledText.setForeground(descriptionBoxStyledText.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
	}

	private void initializeDescriptionLabel(Composite top) {
		Label descriptionBoxLabel = new Label(top, SWT.CENTER);
		descriptionBoxLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false, 2, 1));
		descriptionBoxLabel.setText("Description");
	}

	private void initializeEditorAreas(Composite top) {
		setTitleImage(input.createImage());
		initializeNameArea(top);
		initializeDescriptionArea(top);
	}

	private void initializeLayout(Composite top) {
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		top.setLayout(layout);
	}

	public void modifyText(ModifyEvent e) {
		markAsDirty();
	}

	private void initializeNameArea(Composite top) {
		initializeNameLabel(top);
		initializeNameBox(top);
	}

	private void initializeNameBox(Composite top) {
		nameBox = new Text(top, SWT.BORDER | SWT.SINGLE);
		nameBox.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, false, false));
		nameBox.setEditable(true);
		nameBox.setBackground(nameBox.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
		nameBox.setForeground(nameBox.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
	}

	private void initializeNameLabel(Composite top) {
		Label nameBoxLabel = new Label(top, SWT.CENTER);
		nameBoxLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
		nameBoxLabel.setText("Name");
	}

	@Override
	public boolean isDirty() {
		return dirty;
	}

	@Override
	public boolean isSaveAsAllowed() {
		return false;
	}

	private void markAsDirty() {
		unsubscribeFromEditorAreaChanges();
		setDirty(true);
	}

	private void markAsNotDirty() {
		subscribeToEditorAreaChanges();
		setDirty(false);
	}

	private void setDirty(boolean newDirty) {
		dirty = newDirty;
		firePropertyChange(PROP_DIRTY);
	}

	@Override
	public void setFocus() {
		if((nameBox == null) || (nameBox.isDisposed())) return;
		nameBox.setFocus();
	}

	private void subscribeToEditorAreaChanges() {
		if(subscribed) return;
		nameBox.addModifyListener(this);
		descriptionBoxStyledText.addModifyListener(this);
		subscribed = true;
	}

	private void unsubscribeFromEditorAreaChanges() {
		if(!subscribed) return;
		nameBox.addModifyListener(this);
		descriptionBoxStyledText.addModifyListener(this);
		subscribed = false;
	}
}
